#include "dom.h"

model::dom::dom()
:node(0), is_managed(true)
{

}

model::dom::dom(const string &name)
: is_managed(false)
{
	node = iks_new(name.c_str());
}

model::dom::~dom()
{
	if(node != 0 && !is_managed) {
		iks_delete(node);
	}
}

model::dom::dom(const model::dom &d) 
{
	if(d.get()) {
		is_managed = false;
		node = iks_copy(d.node);
	} else {
		node = 0;
	}
}

model::dom& model::dom::operator = (const model::dom &d)
{
	if(this == &d) {
		return *this;
	}
	if(node && !is_managed) {
		iks_delete(node);
	}
	if(d.node) {
		is_managed = false;
		node = iks_copy(d.node);
	} else {
		node = 0;
	}
}

model::dom::ptr model::dom::next() 
{
	if(node != 0) {
		iks *tmp = iks_next(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::prev()
{
	if(node != 0) {
		iks *tmp = iks_prev(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::parent()
{
	if(node != 0) {
		iks *tmp = iks_parent(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::child()
{
	if(node != 0) {
		iks *tmp = iks_child(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::attrib()
{
	if(node != 0) {
		iks *tmp = iks_attrib(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::root()
{
	if(node != 0) {
		iks *tmp = iks_root(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::next_tag()
{
	if(node != 0) {
		iks *tmp = iks_next_tag(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::prev_tag()
{
	if(node != 0) {
		iks *tmp = iks_prev_tag(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::first_tag()
{
	if(node != 0) {
		iks *tmp = iks_first_tag(node);
		return get_ptr(tmp);
	}
	return get_empty_ptr();
}

model::dom::node_type model::dom::type() const
{
	if(node == 0) {
		return TAG;
	}
	int tmp = iks_type(node);
	switch(tmp) {
		case IKS_TAG:
			return TAG;
		break;
		case IKS_CDATA:
			return CDATA;
		break;
		case IKS_ATTRIBUTE:
			return ATTRIBUTE;
		break;
		default:
			return TAG;
	}
}

string model::dom::name() const
{
	if(node != 0) {
		string str = iks_name(node);
		return str;
	}
	return "";
}

string model::dom::cdata() const
{
	if(node != 0) {
		string str = iks_cdata(node);
		return str;
	}
	return "";
}

bool model::dom::has_children() const
{
	if(node != 0) {
		return iks_has_children(node);
	}
	return false;
}

bool model::dom::has_attribs() const
{
	if(node != 0) {
		return iks_has_attribs(node);
	}
	return false;
}

model::dom::ptr model::dom::find(const string &name)
{
	if(node != 0) {
		return get_ptr(iks_find(node, name.c_str()));
	}
	return get_empty_ptr();
}

string model::dom::find_cdata(const string &name)
{
	if(node != 0) {
		const char *tmp = iks_find_cdata(node, name.c_str());
		if(tmp != 0) {
			return tmp;
		}
	}
	return "";
}

string model::dom::find_attrib(const string &name)
{
	if(node != 0) {
		char *tmp = iks_find_attrib(node, name.c_str());
		if(!tmp) {
			return "";
		}
		return tmp;
	}
	return "";
}

model::dom::ptr model::dom::find_with_attrib(const string &tagname, 
		const string &attrname, const string &val)
{
	if(node != 0) {
		return get_ptr(iks_find_with_attrib(node, tagname.c_str(),
					attrname.c_str(), val.c_str()));
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::insert(const string &name)
{
	if(node != 0) {
		return get_ptr(iks_insert(node, name.c_str()));
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::insert_cdata(const string &name)
{
	if(node != 0) {
		return get_ptr(iks_insert_cdata(node, name.c_str(),
					name.size()));
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::insert_attrib(const string &name, const string &val)
{
	if(node != 0) {
		return get_ptr(iks_insert_attrib(node, name.c_str(),
					val.c_str()));
	}
	return get_empty_ptr();
}

model::dom::ptr model::dom::insert_node(const model::dom &d)
{
	if(d.node != 0 && node != 0) {
		return get_ptr(iks_insert_node(node, d.node));
	}
	return get_empty_ptr();
}

void model::dom::hide()
{
	if(node != 0) {
		iks_hide(node);
	}
}

model::dom::ptr model::dom::get_empty_ptr()
{
	model::dom::ptr p(new dom());
	return p;
}

model::dom::ptr model::dom::get_ptr(iks *node)
{
	model::dom::ptr p(new dom(node));
	return p;
}

model::dom::operator bool() const
{
	return node != 0;
}

string model::dom::to_string() const
{
	if(node) {
		iks* hack = const_cast<iks*>(node);	// hack
		char *tmp = iks_string(0, hack);
		string rw = tmp;
		iks_free(tmp);
		return rw;
	}
	return "";
}

bool model::dom::save(const string &filename) const
{
	if(node != 0) {
		iks* tmp = const_cast<iks*>(node);		// hack!
		return iks_save(filename.c_str(), tmp) == IKS_OK;
	}
	return false;
}

bool model::dom::load(const string &filename) 
{
	if(!is_managed) {
		iks_delete(node);
	}
	is_managed = false;
	return iks_load(filename.c_str(), &node) == IKS_OK;
}

